package com.nhncorp.pleiades.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.EnumSet;

import com.nhncorp.pleiades.persistence.LockStatus;
import com.nhncorp.pleiades.protocol.LockMetaData;

public interface LockService {

  /** Locking modes */
  public static enum LockMode {
    LOCK_SHARED,        // Multiple readers
    LOCK_EXCLUSIVE      // Single writer
  }
  
  /** Event types client can register for. */
  public static enum Events {
    CONTENTS_CHANGED,   // Contents of node changed
    NODE_ADDED,        // node added
    NODE_REMOVED,      // node removed
    NODE_MODIFIED,     // node modified
    MASTER_FAILOVER,    // Master lock server failed over
    SESSION_WARNING,     // Unable to communicate with lock server - session in jeopardy
    SESSION_SAFE,        // Communicated with lock server before time out - session safe
    SESSION_EXPIRED,      // Unable to communicate with lock server - session invalid
    LOCK_EXPIRED,    // lock is released due to client session expiration
    CLIENT_EXPIRED    // client is expired due to session expiration
  }

  /**
   * Acquire a lock. Block if the lock cannot be obtained immediately.
   * @param mode one of the lock modes above
   */
  public boolean getLock(String path, LockMode mode) throws IOException;
  public boolean getLock(String path, byte[] medaData, LockMode mode) throws IOException;
  /** This is for C API based on JNI */
  public boolean getLock(String path, short mode) throws IOException;
  
  public LockStatus getLockStatus(String path) throws IOException;
  
  /**
   * Attempt to acquire a lock. Do not block if the lock cannot be obtained immediately.
   * @param mode - one of the lock modes above
   * @return - true if lock was acquired, false if lock was not acquired.
   */
  public boolean tryLock(String path, LockMode mode) throws IOException;
  /** This is for C API based on JNI */  
  public boolean tryLock(String path, short mode) throws IOException;
  
  /** Releases the currently held lock */
  public boolean releaseLock(String path, LockMode mode)throws IOException;
  /** This is for C API based on JNI */
  public boolean releaseLock(String path, short mode) throws IOException;
  
  /** Releases all the locks currently held */
  public boolean releaseAll() throws IOException;
  
  /** Returns true if the memory lock exist */
  public boolean lockExist(String path)throws IOException;
  
  /** Returns the meta data for the children of a path */
  public LockStatus[] listLock(String path) throws IOException; 
  
  /** lock and write metaData to filesystem. also generate events*/
  public boolean createNode(LockMetaData metaData) throws IOException;  
  public boolean createNode(LockMetaData metaData, boolean overWrite) throws IOException;  
  public boolean createNode(LockMetaData metaData, boolean overWrite, boolean isDirectory) throws IOException;  
  
  /** Deletes the node if it has no children */
  public boolean deleteNode(String path) throws IOException;  
  
  /** Deletes the node. if is has childern, delete the children node */
  public boolean deleteNode(String path, boolean recursive) throws IOException;    
  
  /** Returns the contents of the node (files only) */
  public String getContents(String path) throws IOException ;  
  
  /**
   * Sets the contents of the node (files only)
   * @param contents
   */
  public boolean setContents(String path, String contents) throws IOException;  
  
  /** Returns true if the node exist */
  public boolean exist(String path) throws IOException;  

  /** Returns the meta data for the node */
  public LockMetaData getMetaData(String path) throws IOException;  
  public LockMetaData[] getMetaDataList(String path, boolean includeDirectory) throws IOException;
  
  /** Returns the names and meta data for the children of a directory */
  public Map<String, LockMetaData> readDir(String path) throws IOException ; 
  public Map<String, LockMetaData> readDir(String path, boolean includeDirectory) throws IOException ;  
  
  /**
   * Register to receive lock server events
   * @param handler - event handler object
   * @param eventMask -  mask of desired event types, default to null  * 
   */
  
  public void setEventHandler(LockEventHandler handler) throws IOException;
  public void setEventHandler(LockEventHandler handler, EnumSet<Events> eventMask) throws IOException;  
  /** This is for C API based on JNI */ 
  public void setEventHandler(LockEventHandler handler, int mask) throws IOException;
  
  /** Get event handler instance of the client */
  public LockEventHandler getEventHandler();
  
  /** Terminates session. Does not deallocate resources */
  public void poison();
  
  /** Restart session. Does not allocate resources */
  public void restartSession();
  
  /** Terminates session. Releases allocated resources. */
  public void close();
  
  /** Get all the lock Information.  for debugging and need password to access*/
  public String getAllLockStatus() throws IOException;
  
  /** Get InputStream of File on DFS */
  public InputStream dfs_open(String path);
  
  /** Get OutputStream of File on DFS */
  public OutputStream dfs_create(String path);
  
  /** Delete File on DFS */
  public boolean dfs_delete(String path);
}
